package com.service.impl;


import com.alibaba.fastjson2.JSONObject;
import com.domain.entity.*;
import com.domain.req.AddAccessoryReq;
import com.domain.req.PageReq;
import com.domain.req.UpdateAccessoryReq;
import com.domain.vo.AccessoryPageListVO;
import com.exception.ServiceException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mapper.AccessoryMapper;
import com.mapper.AssembleMapper;
import com.mapper.AssortMapper;
import com.mapper.GoodsMapper;
import com.service.AccessoryService;
import com.service.AssortService;
import com.service.GoodsService;
import com.utils.ValidatorUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author caishenao
* @description 针对表【accessory】的数据库操作Service实现
* @createDate 2023-10-12 20:05:26
*/
@Service
@Slf4j
public class AccessoryServiceImpl implements AccessoryService{

    @Autowired
    private AssortMapper assortMapper;

    @Autowired
    private AccessoryMapper accessoryMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private AssembleMapper assembleMapper;

    @Autowired
    private GoodsService goodsService;

    /**
     * 新增配件
     *
     * @param addAccessoryReq 新增配件请求
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addAccessory(AddAccessoryReq addAccessoryReq) {
        // 1. 数据校验
        ValidatorUtils.validateEntity(addAccessoryReq);

        // 2. 判断分类是否存在
        Assort assort = assortMapper.getById(addAccessoryReq.getAssortId());
        if (assort == null) {
            log.error("分类不存在!");
            throw new ServiceException("分类信息不存在!");
        }

        // 3. 转换为配件对象
        Accessory accessory = addAccessoryReqConversion(addAccessoryReq);

        // 4. 插入对象
        accessoryMapper.insert(accessory);

    }

    /**
     * 根据配件id删除配件信息
     *
     * @param id 配件id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Integer id) {
        // 1. 判断配件是否存在
        Accessory accessory = accessoryMapper.getById(id);
        if (accessory == null) {
            log.error("配件信息不存在，无法删除！");
            throw new ServiceException("配件信息不存在，无法删除!");
        }

        // 2. 查询组装表中的货物信息
        List<Assemble> assembleList = assembleMapper.listByAccessoryId(id);

        // 2. 根据id删除配件信息
        accessoryMapper.deleteById(id);

        // 3. 删除组装表中的信息
        assembleMapper.deleteByAccessoryId(id);

        // 4. 修改商品的进货价和售价
        Set<Integer> goodsSet = assembleList.stream().map(Assemble::getGoodsId).collect(Collectors.toSet());
        for (Integer goodsId : goodsSet) {
            goodsService.recalculateByGoodsId(goodsId);
        }


    }

    /**
     * 根据配件id修改配件信息
     *
     * @param updateAccessoryReq 配件的修改请求
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(UpdateAccessoryReq updateAccessoryReq) {
        // 1. 数据校验
        ValidatorUtils.validateEntity(updateAccessoryReq);

        // 2. 判断配件信息是否存在
        Accessory accessory = accessoryMapper.getById(updateAccessoryReq.getId());
        if (accessory == null) {
            // 配件信息为空，无法修改
            log.error("id为:{}的配件信息不存在,无法修改!", JSONObject.toJSONString(updateAccessoryReq.getId()));
            throw new ServiceException("配件信息不存在,无法修改!");
        }

        // 3. 判断分类是否存在
        Assort assort = assortMapper.getById(updateAccessoryReq.getAssortId());
        if (assort == null) {
            // 修改的分类信息不存在
            log.error("id为:{}的分类信息不存在，无法修改!", JSONObject.toJSONString(updateAccessoryReq.getAssortId()));
            throw new ServiceException("分类信息不存在，无法修改!");
        }

        // 4. 将请求转换为配件实体对象
        Accessory updateAccessory = updateAccessoryReqConversion(updateAccessoryReq);
        // 5. 更新数据库
        accessoryMapper.updateById(updateAccessory);

        if (!accessory.getInputPrice().equals(updateAccessoryReq.getInputPrice()) || !accessory.getSellPrice().equals(updateAccessoryReq.getSellPrice())) {
            // 6.根据配件表，修改使用该配件的所有商品的进货价和售价
            goodsService.recalculateByAccessoryId(accessory.getId(), accessory.getSellPrice(), accessory.getInputPrice());
        }
    }

    /**
     * 根据商品id分页查询配件数据
     *
     * @param goodsId 商品id
     * @return 分页数据
     */
    @Override
    public List<AccessoryPageListVO> listByGoodsId(Integer goodsId) {
        log.info("listByGoodsId的入参:{}", JSONObject.toJSONString(goodsId));
        // 1. 判断商品是否存在
        Goods goods = goodsMapper.getById(goodsId);
        if (goods == null) {
            // 商品不存在
            log.error("商品不存在,没有配件!");
            throw new ServiceException("商品不存在,没有配件信息");
        }

        // 2. 开启分页，查询组装表的信息
        List<Assemble> assembleList = assembleMapper.listByGoodsId(goodsId);

        // 3. 根据组装表中的配件信息，查询配件
        List<Integer> accessoryIdList = assembleList.stream().map(Assemble::getAccessoryId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(accessoryIdList)) {
            log.warn("商品无配件！");
            return new ArrayList<>();
        }

        // 4. 查询
        List<AccessoryPageListVO> accessoryList = accessoryMapper.listByIdList(accessoryIdList);
        log.info("listByGoodsId的出参:{}", JSONObject.toJSONString(accessoryIdList));
        return accessoryList;
    }

    /**
     * 分页查询配件信息
     *
     * @param pageReq 分页请求
     * @param accessory 要查询的配件信息
     * @return 带有非也信息的配件信息激活
     */
    @Override
    public PageInfo<AccessoryPageListVO> pageList(PageReq pageReq, Accessory accessory) {
        // 1. 创建分页请求
        PageHelper.startPage(pageReq.getPageNum(),pageReq.getPageSize());
        List<AccessoryPageListVO> list = accessoryMapper.list(accessory);
        PageInfo<AccessoryPageListVO> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    /**
     * 根据配件id查询配件信息
     *
     * @param id 配件id
     * @return 配件信息
     */
    @Override
    public Accessory getById(Integer id) {
        Accessory accessory = accessoryMapper.getById(id);
        // 根据分类id查询分类信息
        Integer assortId = accessory.getAssortId();
        Assort assort = assortMapper.getById(assortId);
        accessory.setAssort(assort);
        return accessory;
    }

    /**
     * 根据配件名称查询
     * @param name 配件名称
     * @return 模糊查询的结果
     */
    @Override
    public List<Accessory> searchByName(String name) {
        List<Accessory> list = accessoryMapper.listByName(name);
        return list;
    }

    /**
     * 将修改请求转换为配件对象
     *
     * @param updateAccessoryReq 修改请求
     * @return 配件对象
     */
    private Accessory updateAccessoryReqConversion(UpdateAccessoryReq updateAccessoryReq) {
        Accessory accessory = new Accessory();
        accessory.setId(updateAccessoryReq.getId());
        accessory.setAssortId(updateAccessoryReq.getAssortId());
        accessory.setName(updateAccessoryReq.getName());
        accessory.setSystemArg(updateAccessoryReq.getSystemArg());
        accessory.setSellPrice(updateAccessoryReq.getSellPrice());
        accessory.setInputPrice(updateAccessoryReq.getInputPrice());
        accessory.setUpdateTime(new Date());
        return accessory;
    }

    /**
     * 配件新增转换为配件实体对象
     *
     * @param addAccessoryReq 新增配件转换请求
     * @return 配件实体对象
     */
    private Accessory addAccessoryReqConversion(AddAccessoryReq addAccessoryReq) {
        Accessory accessory = new Accessory();
        accessory.setAssortId(addAccessoryReq.getAssortId());
        accessory.setName(addAccessoryReq.getName());
        accessory.setSystemArg(addAccessoryReq.getSystemArg());
        accessory.setSellPrice(addAccessoryReq.getSellPrice());
        accessory.setInputPrice(addAccessoryReq.getInputPrice());
        accessory.setCreateTime(new Date());
        return accessory;
    }
}




